home *** CD-ROM | disk | FTP | other *** search
/ Acorn User: China / Acorn User China CD-ROM (UK) (Disc A) / Acorn User China CD-ROM (UK) (Disc A).bin / HENSA / FILE / BBCTAPE.ARC / !BBCTape_BBCLoad < prev    next >
Encoding:
Text File  |  1991-02-26  |  8.1 KB  |  324 lines

  1. MODE 7
  2. *TAPE
  3. PAGE = &E00
  4. REM
  5. REM BBC end of !BBCTape application
  6. REM
  7. REM (C) S. Burke, 26/2/91
  8. REM
  9. REM The next few lines define where the buffers are, where the
  10. REM code goes and where the file loads to.
  11. REM
  12. :
  13. name       = &0B00
  14. name_high  = &0B
  15. name_low   = &00
  16. block      = &0B10
  17. block_high = &0B
  18. block_low  = &10
  19. code_start = &0B30
  20. load_page  = &0E
  21. :
  22. osfind = &FFCE
  23. osbget = &FFD7
  24. osfile = &FFDD  :REM Page 335 of the Advanced User Guide is wrong!
  25. osbyte = &FFF4
  26. :
  27. FOR opt%=0 TO 3 STEP 3
  28. P% = code_start
  29. [OPT opt%
  30. .go
  31.           LDX #0
  32.           LDA #2
  33.           JSR osbyte        \ disable RS423
  34.           LDX #0
  35.           LDA #15
  36.           JSR osbyte        \ flush all buffers
  37.           LDX #2
  38.           TXA
  39.           JSR osbyte        \ enable RS423 receive
  40. .mainloop
  41.           LDA #&0D
  42.           STA name          \ null name
  43.           JSR handshake
  44. :
  45.           JSR get           \ get command
  46.           CPY #&C0
  47.           BEQ end           \ quit
  48. :
  49.           CPY #&30
  50.           BNE load
  51.           JSR put_ok        \ confirm command
  52.           JSR get_name      \ get filename
  53.           JSR handshake
  54.           JSR get
  55. .load
  56.           CPY #&0C
  57.           BNE load_byte
  58.           JSR put_ok        \ confirm command
  59.           JSR load_file
  60.           JSR send_file
  61.           JMP mainloop
  62. .load_byte
  63.           CPY #&03
  64.           BNE command_error
  65.           JSR put_ok        \ confirm command
  66.           JSR load_bget
  67.           JSR send_file
  68.           JMP mainloop
  69. .command_error
  70.           LDA #0
  71.           JSR put           \ command error
  72.           JMP mainloop
  73. .end
  74.           RTS
  75. .load_file
  76.           LDA #name_low     \ set up parameter block
  77.           STA block
  78.           LDA #name_high
  79.           STA block+1
  80.           LDA #0
  81.           STA block+2
  82.           STA block+6
  83.           LDA #load_page
  84.           STA block+3
  85.           LDA #&FF
  86.           STA block+4
  87.           STA block+5
  88.           LDX #block_low
  89.           LDY #block_high
  90.           JSR osfile        \ load file
  91.           LDA block+10
  92.           STA &71
  93.           LDA block+11
  94.           STA &72           \ put file length in &71, &72
  95.           JSR read_load_exec
  96.           JMP read_name     \ get load/exec address and name
  97. .load_bget
  98.           LDA #0
  99.           STA &71:STA &72   \ file length in &71, &72
  100.           STA &73
  101.           LDA #load_page
  102.           STA &74           \ load address in &73, &74
  103. :
  104.           LDX #name_low
  105.           LDY #name_high
  106.           LDA #&40
  107.           JSR osfind        \ open file
  108.           CMP #0
  109.           BEQ end           \ open failed?
  110.           STA &70           \ file handle
  111.           LDY #0
  112. .loop
  113.           JSR escape        \ check for escape
  114.           TYA:TAX           \ no TYX instruction!
  115.           LDY &70
  116.           JSR osbget        \ get byte
  117.           PHA:TXA:TAY:PLA   \ just TXY!
  118.           BCS eof           \ end of file?
  119.           STA (&73),Y       \ can't use X register
  120.           INY
  121.           BNE loop          \ done 256 bytes?
  122.           INC &72:INC &74   \ increment high bytes of counters
  123.           BPL loop          \ should always be taken
  124. .eof
  125.           STY &71:STY &73   \ set low bytes of counters
  126.           JSR read_load_exec
  127.           JSR read_name     \ get load/exec address and name
  128.           LDY &70
  129.           LDA #0
  130.           JMP osfind        \ close file
  131. .read_name
  132.           LDX #&FF
  133. .nameloop
  134.           INX
  135.           CPX #&C
  136.           BEQ too_far
  137.           LDA &3B2,X        \ pull filename out of cassette workspace
  138.           STA name,X        \ see AUG p. 279
  139.           BNE nameloop
  140. .too_far
  141.           LDA #&0D
  142.           STA name,X
  143.           RTS
  144. .get_name
  145.           LDX #&FF
  146.           STX &81           \ "get" corrupts registers
  147. .get_char
  148.           CPX #&B
  149.           BEQ too_far
  150.           JSR get           \ get filename from Arc
  151.           TYA
  152.           INC &81   
  153.           LDX &81
  154.           STA name,X
  155.           CMP #&0D
  156.           BNE get_char
  157.           RTS
  158. .read_load_exec
  159.           LDX #8
  160. .load_exec_loop
  161.           LDA &3BD,X        \ load/exec address from cassette workspace
  162.           STA &81,X
  163.           DEX
  164.           BNE load_exec_loop
  165.           RTS
  166. .handshake
  167.           LDA #ASC("S")
  168.           JSR put
  169.           LDA #ASC("B")
  170.           JSR put           \ send "SB" ...
  171.           JSR get
  172.           CPY #ASC("s")
  173.           BNE handshake
  174.           JSR get
  175.           CPY #ASC("b")
  176.           BNE handshake     \ ... and receive "sb" to handshake
  177.           RTS
  178. .send_file
  179.           LDA &71
  180.           JSR put
  181.           LDA &72
  182.           JSR put           \ send file length
  183. :
  184.           LDA #load_page
  185.           STA &74
  186.           LDA #0 
  187.           STA &73           \ reset load address
  188.           DEC &72           \ need this for test below
  189.           BMI last_block    \ file length < 256 bytes?
  190.           STA &80           \ block length = 0 ( = 256)
  191. .send_block
  192.           JSR put_ok        \ not eof
  193.           LDA #3            \ send length 3 times
  194.           STA &76           \ use CRC low byte as counter
  195. .lenout
  196.           LDA &80
  197.           JSR put           \ output block length
  198.           DEC &76
  199.           BNE lenout        \ CRC low byte zero at exit
  200.           LDY #0
  201.           STY &75           \ initialise CRC high byte
  202. .send_byte
  203.           STY &70           \ save offset
  204.           LDA (&73),Y       \ load next byte ...
  205.           PHA
  206.           JSR put
  207.           PLA               \ get character back
  208.           JSR crc           \ update crc
  209.           LDY &70
  210.           INY               \ increment offset
  211.           CPY &80
  212.           BNE send_byte     \ end of block?
  213. :
  214.           LDA &75
  215.           JSR put           \ output CRC high byte
  216.           LDA &76
  217.           JSR put           \ output CRC low byte
  218. :
  219.           JSR get           \ look for confirmation
  220.           TYA
  221.           BEQ send_block    \ zero means error, so do again
  222. :
  223.           INC &74           \ increment address high byte
  224.           DEC &72           \ decrement length high byte
  225.           BPL send_block    \ are we finished?
  226. .last_block
  227.           LDY #0
  228.           LDA &71           \ length of last block
  229.           STY &71           \ set length to zero
  230.           STA &80
  231.           BNE send_block    \ output if non-zero
  232.           LDA #0
  233.           JSR put           \ zero marks eof
  234.           JSR put_load_exec \ send the load/exec adress
  235. .put_name                   \ fall through to put_name ...
  236.           LDX #&FF
  237.           STX &81           \ "put" corrupts registers
  238. .put_char                   \ output file name
  239.           INC &81
  240.           LDX &81
  241.           LDA name,X
  242.           PHA
  243.           JSR put
  244.           PLA
  245.           CMP #&0D
  246.           BNE put_char
  247.           RTS
  248. .put_load_exec              \ put out load/exec address
  249.           LDX #0
  250.           STX &81           \ "put" corrupts registers
  251. .put_load_exec_loop
  252.           LDA &82,X
  253.           JSR put
  254.           INC &81
  255.           LDX &81
  256.           CPX #8
  257.           BNE put_load_exec_loop
  258.           RTS
  259. .put_ok
  260.           LDA #&FF
  261. .put
  262.           PHA               \ save value to output
  263.           JSR escape
  264.           LDX #&FD
  265.           LDA #&80
  266.           JSR osbyte        \ get # empty bytes in RS423 output buffer
  267.           CPX #9
  268.           PLA
  269.           BCC put           \ if < 9 bytes remain, wait ...
  270. :
  271.           LDX #2
  272.           TAY
  273.           LDA #&8A
  274.           JMP osbyte        \ ... and send it
  275. .get
  276.           JSR escape
  277.           LDX #1
  278.           LDA #&91
  279.           JSR osbyte        \ read a byte
  280.           BCS get
  281.           RTS
  282. .crc
  283.           EOR &75           \ calculate CRC in &75, &76
  284.           STA &75           \ algorithm from Advanced User Guide
  285.           LDX #8            \ I hope it's right!
  286. .crc_loop
  287.           LDA &75
  288.           ROL A
  289.           BCC b7z
  290.           LDA &75
  291.           EOR #8
  292.           STA &75
  293.           LDA &76
  294.           EOR #&10
  295.           STA &76
  296. .b7z
  297.           ROL &76
  298.           ROL &75
  299.           DEX
  300.           BNE crc_loop
  301.           RTS
  302. .escape
  303.           LDA &FF
  304.           BMI error
  305.           RTS
  306. .error
  307.           LDA #&7E
  308.           JSR osbyte        \ acknowledge escape
  309.           LDX #0
  310.           LDA #&0F
  311.           JSR osbyte        \ flush buffers (just in case)
  312.           LDY #0
  313.           LDA #0
  314.           JSR &FFCE         \ close all files
  315.           BRK
  316. ]
  317. ?P% = &11
  318. P%  = P% + 1
  319. $P% = "Escape" + CHR$0
  320. NEXT opt%
  321. *OPT 1,2
  322. RUN
  323. CALL go
  324.